#include <iostream>
#include <string>

// #define TTTT 0
#define YYYY 0

enum class mesh{
    cell,
    node,
    face
};

enum class ndim{
    twoD,
    threeD
};

enum class frame{
    jasm,
    jaum
};

#if    defined(TTTT)
//将enum class中的类型转换成string，同时也方便输出
const std::string getMeshType(mesh category) {
    switch (category) {
        case mesh::cell: return "TTTTcell";
        case mesh::face: return "TTTTface";
        case mesh::node: return "TTTTnode";
        default: return "Unknown";
    }
}
#elif  !defined(TTTT) && defined(YYYY)
//将enum class中的类型转换成string，同时也方便输出
const std::string getMeshType(mesh category) {
    switch (category) {
        case mesh::cell: return "YYYYcell";
        case mesh::face: return "YYYYface";
        case mesh::node: return "YYYYnode";
        default: return "Unknown";
    }
}
#endif
template<typename mesh_catgories,typename...other_catgories>
class EntityType; 

template<typename mesh_catgories>
class EntityType<mesh_catgories>{
    public:
        EntityType(const mesh catgory): d_mesh_catgory(catgory){
            std::cout << "1 Arg " << std::endl;
        }
        ~EntityType(){}

        std::string getMeshCatogry() const{
            return getMeshType(d_mesh_catgory);
        }
    private:
        mesh_catgories d_mesh_catgory;
};

template<typename mesh_catgories, typename ndim_catgories>
class EntityType<mesh_catgories, ndim_catgories>{
    public:
        EntityType(const mesh mesh_catgory, const ndim ndim_catgory)
        :d_mesh_catgory(mesh_catgory), d_ndim_catgory(ndim_catgory)
        {
            std::cout << "2 Arg " << std::endl;
        }
        ~EntityType(){}
        std::string getMeshCatogry() const{
            return getMeshType(d_mesh_catgory);
        }
    private:
        mesh_catgories d_mesh_catgory;
        ndim_catgories d_ndim_catgory;
};

template<typename mesh_catgories, typename ndim_catgories, typename frame_catgories >
class EntityType<mesh_catgories, ndim_catgories, frame_catgories >{
    public:
        // mesh, ndim 是预先定义的enum class
        EntityType(const mesh mesh_catgory, const ndim ndim_catgory, const frame frame_catgory)
        : d_mesh_catgory(mesh_catgory), d_ndim_catgory(ndim_catgory), d_frame_catgory(frame_catgory)
        {
            std::cout << "3 Arg " << std::endl;
        }
        ~EntityType(){}

    private:
        mesh_catgories  d_mesh_catgory;
        ndim_catgories  d_ndim_catgory;
        frame_catgories d_frame_catgory;
};



int main()
{
    EntityType<mesh> entity(mesh::cell);
    std::cout << entity.getMeshCatogry() << std::endl;
    EntityType<mesh,ndim> entity2(mesh::node,ndim::twoD);
    std::cout << entity2.getMeshCatogry() << std::endl;
    EntityType<mesh,ndim,frame> entity3(mesh::cell,ndim::twoD,frame::jasm);
}